package com.sh.apithirdpay.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.sh.apicommon.common.BaseResponse;
import com.sh.apicommon.common.ErrorCode;
import com.sh.apicommon.common.ResultUtils;
import com.sh.apithirdpay.config.AliPayConfig;
import com.sh.apithirdpay.model.dto.AlipayRequest;
import com.sh.apithirdpay.model.entity.AlipayInfo;
import com.sh.apithirdpay.service.AlipayInfoService;
import com.sh.apithirdpay.utils.OrderPaySuccessMqUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/apithirdpay/alipay")
@Slf4j
public class AlipayController {

    @Resource
    private AliPayConfig aliPayConfig;
    @Resource
    private AlipayInfoService alipayInfoService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private OrderPaySuccessMqUtils orderPaySuccessMqUtils;

    // 沙箱环境网关地址
    String gatewayUrl = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    // 沙箱应用 ID
    String appId = "9021000141613097";
    // 私钥
    String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCXYawrVCjuA5NfOINW+XJc2XmvBIoySXzQ19gut1o39J/oEpzi0FLRyWRpA9spPgQBGQ00N6mRIbzQYxHYrXfN8Kla0DU6H0Vm2Oo/MDKYH0BCues/n/aORoixLGgF/M004mZT+0DVbT/6IBnJ/l3aO1atCPEk3rItLL+9Jpi0EVA9WjY0VMwk2jwA1sgmNm0kTesI+a3mZqXt3gLQr8H1HPNeANP72pa5mHkEoPcHYE5QS3aYgjZywekRZLn0QC0fZSYsA5jLvK/V7qO82cXKMbtWbTUQnztKRUhCMUdw0/kk2SoIHeSRO17J93UcA4L9jOaZTD9EOy4MpV2sIVsNAgMBAAECggEAGMTHadN8Wu1E2KijfMCVwLFoooVIo0+412bpnUMsxMkGvO8GsmnJkz+zaSdTXZ0jBJb3vRp6aR+vCB2dlulTF+QPoac9fkQNk/Vb5njZXmCGoCRRZHik28SYqvyMDKa/YK7GdWk/w2v7ss47yfwPmRxqYyd6ZUD2wEN5H9bH13ZYy75QUxiBwqYtuoDbsp5FJSHYKxAmqANpwTflCfi8JrMQapoDUjfk+PSKAifI1JnAw4YkurcRjkY4w4cdSeIf2MWhuGHG1d6ZLu0qjIYMFxIiIRPLYVfSHdK5CTFHVf3n8QdsmUYnRQfYD350W9T2qEZCTMLGduysQr2maR2FdQKBgQDfor4WnczbkBbwIYnQPGBreWGDOve/PSFEKgvaaWqFvU/TyRrDjVzVGkVygQszrkrQIZwyqat741DonNlOuT3wBih1w9gY3WU4jRisarmGWI+I4gsa9EK209IuXxAk0l86a4m51OiCnsEpTV/jm9SKJ73gaB0C8g6Q8dVUKFPiGwKBgQCtSg6Ab0lMTQwOGBtIMKWSbfMheXBCpU5padMbTMB+SmTW3qKM89Jon73o6uqQRcGLI6g3bSkWWOswBKBojoKFCH1ygGPcYRfdVT3s94i6s7ww5dV5RNjFK2TT8EziLUOXGD+F9NT3fS6fN1hs5SmWtSzPo8cLYvptIdVt1rHJ9wKBgB2sgnyNw7j+jYyfZqHy4PhhysaW9Hizq85Xper9Qd0tGYKIlLyN7Vt5eO2QoePhpJupWgh+6votV3cGGO+RNN68cnHt4qap+dxfHH8ESknBRoprM/4HmzKXOLReeM3p/CjMTCIUViW+2vKYCbkx3CnYzCESr4bMh5JEBIJ+N2MxAoGABVE/bqt7iU7X7trIg4eSnRKooj9StYjTBiMMKktJoNZxj7JXNJIKw9EbB7mlpvWtAbL/Z2v/FcN2vAt4TJ0K3kArcUcFSW7lR5JlCw9xb6EyRiHXUhhNuochWeuGwG35I/rHgDnKCyoZMyOEoBrMEubOUDTLV8sauhyOqwcqf3MCgYAWchHSyfMRxnnaUmZJG5M1Q4s1BBtl8zevJN8jlJVQ+iHflOg5aZ3e8958WYa2Gl2ngM/DH3I4kDoEkDcAbAXZlOdvsTOFoO8oTldRCxXzr7n1TOjEqDzLCjc8L31bY5B/I5IiliPMCU1kM5xURFHoNyRRPxbdwu3rwl091LnSgw==";
    // 格式
    String format = "json";
    // 字符集
    String charset = "UTF-8";
    // 支付宝公钥（从沙箱获取）
    String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxnCYiDm8iswoXc179d/TbnRrM6jWSeS0Fa9A+lh12JBWKzSEQjj09AVSmZDOSX4iBk1WoJat7G941QXvbjDMX4Zvs+wc/N9nJUH8xTFw/XT+fVMCLP5k0+ljuEzKpomxWUxnq1PcStezoqWcCd2S6VQ9kCBvkBOH+6GDB1ZUzjNCrU8OyGQsGugNr2LIHzGR/JOEmfl3xr1SXElMVudQkrjW4yS1lCb5WJU1jQOdK04/ZoKmKxT5cydrOmHcceNWMTpDnTiO4EKQQzG9miIB0hT/s1V+gmtAN1GWIKaUg4bJ9xkjbVeUHo96juIw91Cs5Izq/RB1ZzP7JEMU7DVUPwIDAQAB";
    // 签名方式
    String signType = "RSA2";


    private static final String ALIPAY_TRADE_SUCCESS_RECORD="alipay_success_recode:";
    private static final String EXIST_KEY_VALUE = "exist";
    @PostMapping("/payCode")
    // 方法接收一个包含支付信息的请求对象，并返回一个包含支付二维码 Base64 编码的响应对象
    public BaseResponse<String> payCodeCode(@RequestBody AlipayRequest alipayRequest, HttpServletResponse httpResponse) throws AlipayApiException, IOException {
        // 从请求对象中获取订单号、商品描述和总金额
        String outTradeNo = alipayRequest.getTraceNo();
        String subject = alipayRequest.getSubject();
        double totalAmount = alipayRequest.getTotalAmount();
        AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey, format, charset, alipayPublicKey, signType);
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();

        request.setNotifyUrl("http://kc8296ee.natappfree.cc/apithirdpay/alipay/notify");
        request.setReturnUrl("http://localhost:8000/myInterface");
        request.setBizModel(model);
        model.setOutTradeNo(outTradeNo);
        model.setTotalAmount(String.valueOf(totalAmount));
        model.setSubject(subject);

        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        log.info("响应支付二维码详情："+response.getBody());

        String base64 = QrCodeUtil.generateAsBase64(response.getQrCode(), new QrConfig(300, 300), "png");

        return ResultUtils.success(base64);

    }

    /**
     * 支付成功回调,注意这里必须是POST接口
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping("/notify")
    public synchronized String payNotify(HttpServletRequest request) {
        try {
            if ("TRADE_SUCCESS".equals(request.getParameter("trade_status"))) {
                Map<String, String> params = new HashMap<>();
                Map<String, String[]> requestParams = request.getParameterMap();
                for (String name : requestParams.keySet()) {
                    params.put(name, request.getParameter(name));
                }

                if (AlipaySignature.rsaCheckV1(params, aliPayConfig.getPublicKey(), aliPayConfig.getCharset(), aliPayConfig.getSignType())) {
                    log.info("支付成功:{}", params);
                    Object outTradeNo = stringRedisTemplate.opsForValue().get(ALIPAY_TRADE_SUCCESS_RECORD + params.get("out_trade_no"));
                    if (outTradeNo == null) {
                        AlipayInfo alipayInfo = new AlipayInfo();
                        // 验签通过，将订单信息存入数据库
                        alipayInfo.setSubject(params.get("subject"));
                        alipayInfo.setTradeStatus(params.get("trade_status"));
                        alipayInfo.setTradeNo(params.get("trade_no"));
                        alipayInfo.setOrderNumber(params.get("out_trade_no"));
                        alipayInfo.setTotalAmount(Double.valueOf(params.get("total_amount")));
                        alipayInfo.setBuyerId(params.get("buyer_id"));
                        alipayInfo.setGmtPayment(DateUtil.parse(params.get("gmt_payment")));
                        alipayInfo.setBuyerPayAmount(Double.valueOf(params.get("buyer_pay_amount")));
                        alipayInfoService.save(alipayInfo);
                        stringRedisTemplate.opsForValue().set(ALIPAY_TRADE_SUCCESS_RECORD + alipayInfo.getOrderNumber(), EXIST_KEY_VALUE, 30, TimeUnit.MINUTES);
                        orderPaySuccessMqUtils.sendOrderPaySuccess(params.get("out_trade_no"));
                    }
                } else {
                    log.warn("支付宝验签失败，params: {}", params);
                }
            }
            return "success";
        } catch (Exception e) {
            log.error("支付宝回调处理异常", e);
            return "failure";
        }
    }


//    @GetMapping("/checkOrderStatus")
//    public BaseResponse<String> checkOrderStatus(String orderId) {
//        AlipayInfo alipayInfo = alipayInfoService.getByOrderId(orderId);
//        if (alipayInfo != null && "TRADE_SUCCESS".equals(alipayInfo.getTradeStatus())) {
//            return ResultUtils.success("PAID");
//        }
//        return ResultUtils.error(ErrorCode.OPERATION_ERROR, "未支付");
//    }

}